/*
This is part of Screenbar, which is based in part on the Litestep
shell source code.

Copyright (C) 2008-2009 Jim Babcock
Copyright (C) 1997-2009 The LiteStep Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "stdafx.h"

AnimElement::AnimElement(int trigger, LayoutLocation location, Animation *animation)
	:SubstituteElement(location.element)
{
	assert(location.element != NULL);
	this->prefix = animation->getPrefix();
	this->state.animation = animation;
	this->state.startTime = getSystemTime();
	this->state.trigger = trigger;
	this->state.direction = location.context.window->getAnimationDirection();
	
	this->animating = true;
}

AnimElement::~AnimElement()
{
}

bool AnimElement::isFinished()
{
	state.updateTime();
	return state.animation->isFinished(&state);
}

int AnimElement::getTrigger()
{
	return state.trigger;
}

bool AnimElement::changed(const LayoutCacheNode *node)
{
	return true;
}

void AnimElement::update(const LayoutCacheNode *node)
{
	state.updateTime();
}

ElementSize AnimElement::getLength(const LayoutCacheNode *node)
{
	return state.animation->getElementSize(&state, node->children[0]->size);
}

void AnimElement::getChildren(LayoutCacheNode *node, vector<LayoutLocation> &outChildren)
{
	assert(child != NULL);
	LayoutLocation childLoc;
	childLoc.element = child;
	childLoc.context = node->context;
	outChildren.push_back(childLoc);
}

void AnimElement::arrangeChildren(LayoutCacheNode *container, vector<LayoutCacheNode*> &children)
{
	for(unsigned ii=0; ii<children.size(); ii++)
		children[ii]->boundingRect = container->boundingRect;
}

void AnimElement::draw(HDC drawContext, const LayoutCacheNode *node)
{
	const LayoutCacheNode *childNode = node->children[0];
	
	int x = node->boundingRect.left;
	int y = node->boundingRect.top;
	int width = node->boundingRect.width;
	int height = node->boundingRect.height;
	
	BackBuffer *backBuf = new BackBuffer(width, height);
	
	XFORM transform;
	transform.eM11 = 1;
	transform.eM12 = 0;
	transform.eM21 = 0;
	transform.eM22 = 1;
	transform.eDx = -x;
	transform.eDy = -y;
	SetGraphicsMode(backBuf->getDC(), GM_ADVANCED);
	SetWorldTransform(backBuf->getDC(), &transform);
	
	memset(backBuf->getBits(), 0, width*height*4);
	
	childNode->element->draw(backBuf->getDC(), childNode);
	
	transform.eDx = transform.eDy = 0;
	SetWorldTransform(backBuf->getDC(), &transform);
	
	state.updateTime();
	state.animation->apply(&state, backBuf->getDC(), drawContext, x, y, width, height);
	
	delete backBuf;
}
